#include "Account.hh"
#include <iostream>

namespace mini_bank {

Account::Account(const std::string& id,
                 const std::string& owner,
                 double initialBalance)
    : accountId(id), ownerName(owner), balance(initialBalance) {}

std::string Account::getId() const { return accountId; }
std::string Account::getOwnerName() const { return ownerName; }
double Account::getBalance() const { return balance; }

void Account::addTransaction(const Transaction& tx) {
    transactions.push_back(tx);
}

const std::vector<Transaction>& Account::getTransactions() const {
    return transactions;
}

// SavingsAccount 实现
bool SavingsAccount::deposit(double amount, const std::string& note, bool isTransfer) {
    if (!isTransfer) {
        std::cout << "Savings account does not support manual deposits.\n";
        return false;
    }
    if (amount <= 0) {
        std::cout << "Invalid transfer amount.\n";
        return false;
    }
    balance += amount;
    return true;
}

bool SavingsAccount::withdraw(double, const std::string&) {
    std::cout << "Savings account does not support withdrawal operations.\n";
    return false;
}

bool SavingsAccount::transfer(Account& target, double amount, const std::string& note, bool isTransfer) {
    if (ownerName != target.getOwnerName() || dynamic_cast<CheckingAccount*>(&target) == nullptr) {
        std::cout << "Savings accounts can only transfer to the same user's checking account.\n";
        return false;
    }
    if (amount <= 0 || balance < amount) {
        std::cout << "Invalid transfer amount or insufficient balance.\n";
        return false;
    }
    balance -= amount;
    if (!target.deposit(amount, note, true)) {
        balance += amount;
        return false;
    }
    return true;
}

bool CheckingAccount::deposit(double amount, const std::string& note, bool isTransfer) {
    if (amount <= 0) {
        std::cout << "Deposit amount must be greater than 0.\n";
        return false;
    }
    balance += amount;
    return true;
}

bool CheckingAccount::withdraw(double amount, const std::string& note) {
    if (amount <= 0 || amount > balance) {
        std::cout << "Invalid withdrawal amount or insufficient balance.\n";
        return false;
    }
    balance -= amount;
    return true;
}

bool CheckingAccount::transfer(Account& target, double amount, const std::string& note, bool isTransfer) {
    if (amount <= 0 || amount > balance) {
        std::cout << "Invalid transfer amount or insufficient balance.\n";
        return false;
    }
    if (!withdraw(amount, note)) return false;
    if (!target.deposit(amount, note, true)) {
        deposit(amount, note);
        return false;
    }
    return true;
}

} // namespace mini_bank